package net.homelinux.chaoswg.io.renga.core.gui.operations;

import javax.swing.JOptionPane;

import net.homelinux.chaoswg.io.renga.core.gui.DrawingArea;
import net.homelinux.chaoswg.io.renga.core.gui.operations.helper.Connection;
import net.homelinux.chaoswg.io.renga.core.gui.operations.visualisations.InputBlockVisualisation;

import org.jdom.Element;

public class FunctionInputOperation extends Operation {
    protected CompositeOperation superOperation  = null;
    protected int isInputNumber = -1;
    protected Object initialValue = null;

    public FunctionInputOperation () {
        this.visualisation = new InputBlockVisualisation (this);
        connections = new Connection[1];
        connections[0] = new Connection();

        visualisation.setInputs(0); //Don't show inputs
        visualisation.setOutputs(1);

        inputs = 1;
        outputs = 1;
    }

    public FunctionInputOperation (final CompositeOperation superOperation, final int isInputNumber) {
        this.id = Operation.nextID++;
        this.superOperation = superOperation;
        this.isInputNumber = isInputNumber;
        this.visualisation = new InputBlockVisualisation (this);

        inputs = 1;
        outputs = 1;

        connections = new Connection[1];
        connections[0] = new Connection();

        visualisation.setInputs(0); //Don't show inputs
        visualisation.setOutputs(1);
    }

    public FunctionInputOperation (final CompositeOperation superOperation) {
        this.superOperation = superOperation;
        this.isInputNumber = 0;
        this.visualisation = new InputBlockVisualisation (this);

        inputs = 1;
        outputs = 1;

        connections = new Connection[1];
        connections[0] = new Connection();

        visualisation.setInputs(0); //Don't show inputs
        visualisation.setOutputs(1);
    }

    public Object getInitialValue () {
        return initialValue;
    }

    public void setInitialValue (final Object initialValue) {
        this.initialValue = initialValue;
    }

    public boolean isConnected (final int i) {
        return i == 0 && superOperation.isConnected(isInputNumber);
    }

    @Override
    public Object apply(final int i) {
        if (i >= outputs) {
            return null;
        }
        if (initialValue != null) {
            result  = initialValue;
        } else {
            final Connection c = superOperation.connections[isInputNumber];

            result = c.getResult();
        }
        
        return result;
    }

    public void clearInitialValue () {
        initialValue = null;
    }

    public String toString () {
        return "Function Input";
    }

    public int getIsInputNumber() {
        return isInputNumber;
    }

    public void setIsInputNumber(final int isInputNumber) {
        this.isInputNumber = isInputNumber;
    }

    @Override
    public String getDoubleClickActionName() {
        return "Set initial value";
    }

    @Override
    public void doubleClick(final DrawingArea dv) {
        String inputValue = JOptionPane.showInputDialog(dv, "Input initial-value", this.getInitialValue());
        if (inputValue != null) {
            if (inputValue.equals("")) {
                this.clearInitialValue();
            } else {
                this.setInitialValue(inputValue);
            }
        }
    }

    public boolean fullyConnected () {
        return isConnected(0) || (initialValue != null);
    }

    public Element writeYourself () {
        final Element toReturn = super.writeYourself();

        final Element superOperationElement = new Element ("superOperation");
        superOperationElement.setText(""+superOperation.getId());
        toReturn.addContent(superOperationElement);

        final Element isInputNumberElement = new Element ("inputNumber");
        isInputNumberElement.setText(""+isInputNumber);
        toReturn.addContent(isInputNumberElement);

        if (initialValue != null) {
            final Element initialvalueElement = new Element("initialValue");
            initialvalueElement.setText(initialValue.toString());
            toReturn.addContent(initialvalueElement);
        }

        return toReturn;
    }

    public CompositeOperation getSuperOperation() {
        return superOperation;
    }

    public void setSuperOperation(final CompositeOperation superOperation) {
        this.superOperation = superOperation;
    }
}
